hvm: Clean up VMCS/VMCB construction.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 22 Nov 2007 19:55:42 +0000 (19:55 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 22 Nov 2007 19:55:42 +0000 (19:55 +0000)
Signed-off-by: Keir Fraser <keir.fraser@eu.citrix.com>
xen/arch/x86/hvm/svm/vmcb.c
xen/arch/x86/hvm/vmx/vmcs.c
xen/include/asm-x86/hvm/svm/vmcb.h

index 2332581ed639e5f903731308227d9b2bf7a506a9..563e4818336a17a4f87fb2cb0e1d66d92f75220f 100644 (file)
@@ -40,8 +40,6 @@
 
 extern int svm_dbg_on;
 
-#define GUEST_SEGMENT_LIMIT 0xffffffff
-
 #define IOPM_SIZE   (12 * 1024)
 #define MSRPM_SIZE  (8  * 1024)
 
@@ -110,7 +108,6 @@ static int construct_vmcb(struct vcpu *v)
 {
     struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
     struct vmcb_struct *vmcb = arch_svm->vmcb;
-    svm_segment_attributes_t attrib;
 
     /* TLB control, and ASID assigment. */
     svm_asid_init_vcpu(v);
@@ -173,12 +170,12 @@ static int construct_vmcb(struct vcpu *v)
     vmcb->efer = EFER_SVME;
 
     /* Guest segment limits. */
-    vmcb->cs.limit = GUEST_SEGMENT_LIMIT;
-    vmcb->es.limit = GUEST_SEGMENT_LIMIT;
-    vmcb->ss.limit = GUEST_SEGMENT_LIMIT;
-    vmcb->ds.limit = GUEST_SEGMENT_LIMIT;
-    vmcb->fs.limit = GUEST_SEGMENT_LIMIT;
-    vmcb->gs.limit = GUEST_SEGMENT_LIMIT;
+    vmcb->cs.limit = ~0u;
+    vmcb->es.limit = ~0u;
+    vmcb->ss.limit = ~0u;
+    vmcb->ds.limit = ~0u;
+    vmcb->fs.limit = ~0u;
+    vmcb->gs.limit = ~0u;
 
     /* Guest segment bases. */
     vmcb->cs.base = 0;
@@ -189,20 +186,12 @@ static int construct_vmcb(struct vcpu *v)
     vmcb->gs.base = 0;
 
     /* Guest segment AR bytes. */
-    attrib.bytes = 0;
-    attrib.fields.type = 0x3; /* type = 3 */
-    attrib.fields.s = 1;      /* code or data, i.e. not system */
-    attrib.fields.dpl = 0;    /* DPL = 0 */
-    attrib.fields.p = 1;      /* segment present */
-    attrib.fields.db = 1;     /* 32-bit */
-    attrib.fields.g = 1;      /* 4K pages in limit */
-    vmcb->es.attr = attrib;
-    vmcb->ss.attr = attrib;
-    vmcb->ds.attr = attrib;
-    vmcb->fs.attr = attrib;
-    vmcb->gs.attr = attrib;
-    attrib.fields.type = 0xb; /* type=0xb -> executable/readable, accessed */
-    vmcb->cs.attr = attrib;
+    vmcb->es.attr.bytes = 0xc93; /* read/write, accessed */
+    vmcb->ss.attr.bytes = 0xc93;
+    vmcb->ds.attr.bytes = 0xc93;
+    vmcb->fs.attr.bytes = 0xc93;
+    vmcb->gs.attr.bytes = 0xc93;
+    vmcb->cs.attr.bytes = 0xc9b; /* exec/read, accessed */
 
     /* Guest IDT. */
     vmcb->idtr.base = 0;
@@ -219,8 +208,7 @@ static int construct_vmcb(struct vcpu *v)
     vmcb->ldtr.attr.bytes = 0;
 
     /* Guest TSS. */
-    attrib.fields.type = 0xb; /* 32-bit TSS (busy) */
-    vmcb->tr.attr = attrib;
+    vmcb->tr.attr.bytes = 0x08b; /* 32-bit TSS (busy) */
     vmcb->tr.base = 0;
     vmcb->tr.limit = 0xff;
 
index 03cf5cbc92d45a0c1b01b283483a54604a17ec11..3a184c55ba6df6f2605c0a4786ebe536c0c48bbd 100644 (file)
@@ -443,11 +443,8 @@ void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr)
     }
 }
 
-#define GUEST_SEGMENT_LIMIT     0xffffffff
-
 static int construct_vmcs(struct vcpu *v)
 {
-    union vmcs_arbytes arbytes;
     uint16_t sysenter_cs;
     unsigned long sysenter_eip;
 
@@ -537,46 +534,39 @@ static int construct_vmcs(struct vcpu *v)
     __vmwrite(GUEST_CS_BASE, 0);
 
     /* Guest segment limits. */
-    __vmwrite(GUEST_ES_LIMIT, GUEST_SEGMENT_LIMIT);
-    __vmwrite(GUEST_SS_LIMIT, GUEST_SEGMENT_LIMIT);
-    __vmwrite(GUEST_DS_LIMIT, GUEST_SEGMENT_LIMIT);
-    __vmwrite(GUEST_FS_LIMIT, GUEST_SEGMENT_LIMIT);
-    __vmwrite(GUEST_GS_LIMIT, GUEST_SEGMENT_LIMIT);
-    __vmwrite(GUEST_CS_LIMIT, GUEST_SEGMENT_LIMIT);
+    __vmwrite(GUEST_ES_LIMIT, ~0u);
+    __vmwrite(GUEST_SS_LIMIT, ~0u);
+    __vmwrite(GUEST_DS_LIMIT, ~0u);
+    __vmwrite(GUEST_FS_LIMIT, ~0u);
+    __vmwrite(GUEST_GS_LIMIT, ~0u);
+    __vmwrite(GUEST_CS_LIMIT, ~0u);
 
     /* Guest segment AR bytes. */
-    arbytes.bytes = 0;
-    arbytes.fields.seg_type = 0x3;          /* type = 3 */
-    arbytes.fields.s = 1;                   /* code or data, i.e. not system */
-    arbytes.fields.dpl = 0;                 /* DPL = 3 */
-    arbytes.fields.p = 1;                   /* segment present */
-    arbytes.fields.default_ops_size = 1;    /* 32-bit */
-    arbytes.fields.g = 1;
-    arbytes.fields.null_bit = 0;            /* not null */
-    __vmwrite(GUEST_ES_AR_BYTES, arbytes.bytes);
-    __vmwrite(GUEST_SS_AR_BYTES, arbytes.bytes);
-    __vmwrite(GUEST_DS_AR_BYTES, arbytes.bytes);
-    __vmwrite(GUEST_FS_AR_BYTES, arbytes.bytes);
-    __vmwrite(GUEST_GS_AR_BYTES, arbytes.bytes);
-    arbytes.fields.seg_type = 0xb;          /* type = 0xb */
-    __vmwrite(GUEST_CS_AR_BYTES, arbytes.bytes);
+    __vmwrite(GUEST_ES_AR_BYTES, 0xc093); /* read/write, accessed */
+    __vmwrite(GUEST_SS_AR_BYTES, 0xc093);
+    __vmwrite(GUEST_DS_AR_BYTES, 0xc093);
+    __vmwrite(GUEST_FS_AR_BYTES, 0xc093);
+    __vmwrite(GUEST_GS_AR_BYTES, 0xc093);
+    __vmwrite(GUEST_CS_AR_BYTES, 0xc09b); /* exec/read, accessed */
+
+    /* Guest IDT. */
+    __vmwrite(GUEST_IDTR_BASE, 0);
+    __vmwrite(GUEST_IDTR_LIMIT, 0);
 
     /* Guest GDT. */
     __vmwrite(GUEST_GDTR_BASE, 0);
     __vmwrite(GUEST_GDTR_LIMIT, 0);
 
-    /* Guest IDT. */
-    __vmwrite(GUEST_IDTR_BASE, 0);
-    __vmwrite(GUEST_IDTR_LIMIT, 0);
+    /* Guest LDT. */
+    __vmwrite(GUEST_LDTR_AR_BYTES, 0x0082); /* LDT */
+    __vmwrite(GUEST_LDTR_SELECTOR, 0);
+    __vmwrite(GUEST_LDTR_BASE, 0);
+    __vmwrite(GUEST_LDTR_LIMIT, 0);
 
-    /* Guest LDT and TSS. */
-    arbytes.fields.s = 0;                   /* not code or data segement */
-    arbytes.fields.seg_type = 0x2;          /* LTD */
-    arbytes.fields.default_ops_size = 0;    /* 16-bit */
-    arbytes.fields.g = 0;
-    __vmwrite(GUEST_LDTR_AR_BYTES, arbytes.bytes);
-    arbytes.fields.seg_type = 0xb;          /* 32-bit TSS (busy) */
-    __vmwrite(GUEST_TR_AR_BYTES, arbytes.bytes);
+    /* Guest TSS. */
+    __vmwrite(GUEST_TR_AR_BYTES, 0x008b); /* 32-bit TSS (busy) */
+    __vmwrite(GUEST_TR_BASE, 0);
+    __vmwrite(GUEST_TR_LIMIT, 0xff);
 
     __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
     __vmwrite(GUEST_DR7, 0);
@@ -600,13 +590,6 @@ static int construct_vmcs(struct vcpu *v)
         __vmwrite(TPR_THRESHOLD, 0);
     }
 
-    __vmwrite(GUEST_LDTR_SELECTOR, 0);
-    __vmwrite(GUEST_LDTR_BASE, 0);
-    __vmwrite(GUEST_LDTR_LIMIT, 0);
-
-    __vmwrite(GUEST_TR_BASE, 0);
-    __vmwrite(GUEST_TR_LIMIT, 0xff);
-
     vmx_vmcs_exit(v);
 
     paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */
index 35e492f36aca0b240080fe1b96037b55f9653646..b5487fc4917527ae41cbb183f7fbfb3f3b844d22 100644 (file)
@@ -303,8 +303,7 @@ enum VMEXIT_EXITCODE
     VMEXIT_INVALID          =  -1
 };
 
-/* Definitions of segment state are borrowed by the generic HVM code. */
-typedef segment_attributes_t svm_segment_attributes_t;
+/* Definition of segment state is borrowed by the generic HVM code. */
 typedef segment_register_t svm_segment_register_t;
 
 typedef union